
#include "rtmp_message.h"
#include <cstdio>
#include <string>
#include <vector>


RtmpHeader::RtmpHeader()
{
    m_format = 0;
    m_chunk_stream = 0;
    m_timestamp    = 0;
    m_calc_timestamp = 0;
    m_body_size    = 0;
    m_type_id      = 0;
    m_stream_id    = 0;
}

RtmpHeader::~RtmpHeader()
{
}

int RtmpHeader::PrintRtmpHeader(char * buffer)
{
    int index = 0;
    index += sprintf(buffer, "fmt:%d|chunk_stream:%d|timestamp:%d|body_size:%d|type_id:%d|stream_id:%d.\n",
            (int)m_format,
            (int)m_chunk_stream,
            m_timestamp,
            m_body_size,
            (int)m_type_id,
            m_stream_id);
    return index;
}

RtmpBody::RtmpBody()
{
    /* m_attr_data = 0; */
}

RtmpBody::~RtmpBody()
{
    for (auto & data : m_amf_value_vec)
    {
        delete data;
    }
    TRACE("release rtmp body, body size : {} and data size : {}", m_amf_value_vec.size(), m_data.size());
    m_data.clear();
}

int RtmpBody::PrintRtmpBody(char * buffer)
{
    int index = 0;
    index += sprintf(buffer, "amf value size:%ld|attr_data:%d|data size:%ld.\n", m_amf_value_vec.size(),(int)m_attr_data.m_media_attr_data, m_data.size());

    return index;
}

RtmpMessage::RtmpMessage():m_header(),m_body()
{

}

RtmpMessage::~RtmpMessage()
{
}

std::string RtmpMessage::PrintRtmpMessage()
{
    char buffer[1024] = {0};
    int index = m_header.PrintRtmpHeader(buffer);
    index += m_body.PrintRtmpBody(buffer + index);
    (void)index;
    return buffer;
}

std::string RtmpMessage::CommandString()
{
    std::string command;
    if (m_body.m_amf_value_vec.empty())
    {
        return "";
    }
    for (auto & data : m_body.m_amf_value_vec)
    {
        if (data->GetValueType() == AMF_STRING) 
        {
            command = ((AmfString*)data)->GetValue();
            break;
        }
    }
    return command;
}

int RtmpMessage::NumberId()
{
    double number = 0;
    for (auto & data : m_body.m_amf_value_vec)
    {
        if (data && data->GetValueType() == AMF_NUMBER)
        {
            number = ((AmfNumber*)data)->GetValue();
            break;
        }
    }
    return number;
}

AmfObject * RtmpMessage::Object()
{
    AmfObject * result = nullptr;
    for (auto & data : m_body.m_amf_value_vec)
    {
        if (data && data->GetValueType() == AMF_START_OBJECT)
        {
            result = (AmfObject*)data;
            break;
        }
    }
    return result;
}

std::string RtmpMessage::UserPass(int i)
{
    if (m_body.m_amf_value_vec.empty())
    {
        return "";
    }
    std::string command;
    for (auto iter = m_body.m_amf_value_vec.begin() + 1; iter != m_body.m_amf_value_vec.end(); iter++)
    {
        if ((*iter)->GetValueType() == AMF_STRING && (--i) == 0)
        {
            command = ((AmfString*)(*iter))->GetValue();
            break;
        }
    }
    return command;
}


void RtmpMessage::PushAmfValue(AmfValue * value)
{
    m_body.m_amf_value_vec.push_back(value);
}

void RtmpMessage::CopyRtmpHeader(const RtmpHeader & header)
{
    m_header = header;
}

